using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Markup;
using Rhizome.Contract;
using Rhizome.Contract.Diag;
using Rhizome.Model.Validation;

namespace Rhizome.Model
{
    [ContentProperty("Action")]
    public abstract class TriggerBase<TPlant> : RuleBase<TPlant>, ITrigger, IValidate
	{
	    /// <summary>
	    /// Trigger action (can be inherited from parent trigger)
	    /// </summary>
		public IAction Action
	    {
            [DebuggerStepThrough]
            get { return GetValue(ActionProperty); }
            [DebuggerStepThrough]
            set { SetValue(ActionProperty, value); }
	    }

        /// <summary>
        /// Optional trigger criterion (can be inherited from parent trigger)
        /// </summary>
		public ICriterion Criterion
        {
            [DebuggerStepThrough]
            get { return GetValue(CriterionProperty); }
            [DebuggerStepThrough]
            set { SetValue(CriterionProperty, value); }
        }

        protected void Trigged()
        {
			Post(InternalTrigged);
        }

        private void InternalTrigged()
    	{
    		var c = Criterion;
    		if (c == null || c.Test()) 
    			Action.Process();
    	}

    	#region Implementation of IValidate

    	public virtual IEnumerable<IValidationResult> GetValidationResults()
    	{
			if (Action == null)
				yield return ValidationResult.ActionIsNull;
    	}

    	#endregion

    	public virtual object GetForwardEvent()
    	{
    		var forwardEvent = Action as IForwardEvent;
    		return
    			forwardEvent != null &&
    			Criterion != null && Criterion.Test()
    				? forwardEvent.GetForwardEvent()
    				: null;
    	}

    	#region Implementation of IStateInitialize

    	public abstract void Initialize();
    	public abstract void Cleanup();

    	#endregion
	}
}